package org.cars.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import org.cars.decoder.StringLineDelimiterDecoder;
import org.cars.netty.server.handler.FirstServerHandler;
import org.cars.netty.server.handler.HeartBeatHandler;

/**
 * Netty服务端<br/>
 * 1、boos对应，IOServer.java中的接受新连接线程，主要负责创建新连接<br/>
 * 2、worker对应 IOClient.java中的负责读取数据的线程，主要用于读取数据以及业务逻辑处理
 *
 * @author 闪电侠
 */
public class NettyServer {
    public static void main(String[] args) {
        //EventLoopGroup相当于线程池, 实际上也实现了线程池
        //bossGroup是用来处理连接的
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        //workerGroup是用来处理io的
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                //添加我们自定义的业务handler
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) {
                        ch.pipeline()
                                .addLast(new SimpleChannelInboundHandler<String>() {
                                    @Override
                                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
                                        System.out.println("channelHandlerContext = " + channelHandlerContext + ", s = " + s);
                                    }
                                })
                                //设置读空闲5秒
                                .addLast(new IdleStateHandler(5, 0, 0))
                                //在IdleStateHandler的后一个加入HeartBeatHandler
                                .addLast(new HeartBeatHandler())
                                .addLast(new StringDecoder())
                                .addLast(new StringLineDelimiterDecoder())
                                .addLast(new DefaultEventExecutorGroup(10), new FirstServerHandler());
                    }
                })
                .bind(8000);
    }
}